package com.sinosoft.cloud.access.handler;

import com.sinosoft.cloud.access.codec.Decoder;
import com.sinosoft.cloud.access.codec.DecoderFactory;
import com.sinosoft.cloud.access.crypto.CryptoBean;
import com.sinosoft.cloud.access.net.AccessControl;
import com.sinosoft.cloud.access.net.MessageObject;
import com.sinosoft.cloud.common.SpringContextUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.ReadTimeoutException;

import static io.netty.channel.ChannelFutureListener.CLOSE;

/**
 * cloud-netty
 *
 * @title: cloud-netty
 * @package: com.sinosoft.cloud.access.handler
 * @author: yangming
 * @date: 2017/12/4 下午2:18
 */
public class RouterReviceHandler extends AbstractRouterHandler {

    private final ChannelHandlerContext ctx;

    public MessageObject messageObject;

    public RouterReviceHandler(ChannelHandlerContext ctx, MessageObject messageObject) {
        this.ctx = ctx;
        this.messageObject = messageObject;
    }

    private DecoderFactory decoderFactory = DecoderFactory.getInstance();

    AccessControl accessControl = SpringContextUtils.getBeanByClass(AccessControl.class);

    @Override
    MessageObject dealMessage(ChannelHandlerContext ctx, MessageObject messageObject) {
        ByteBuf encoded = Unpooled.copiedBuffer(messageObject.getOriginalMsg().getBytes());
        logger.info("接收到CIP返回的报文："+ messageObject.getOriginalMsg());
        this.ctx.writeAndFlush(encoded).addListener(CLOSE);
        ctx.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(CLOSE);
        return messageObject;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (cause instanceof ReadTimeoutException) {

            String errorStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ABCB2I><Header><RetCode>009999</RetCode><RetMsg>系统繁忙，请稍后重试</RetMsg><SerialNo></SerialNo><InsuSerial/><TransDate></TransDate><TranTime></TranTime><BankCode></BankCode><CorpNo></CorpNo><TransCode></TransCode></Header></ABCB2I>";

            CryptoBean cryptoBean = getCryptoBean();
            if (null != cryptoBean) {
                String originalMsg = messageObject.getOriginalMsg().substring(73);
                if (!originalMsg.startsWith("<")) {
                    errorStr = cryptoBean.encryt(errorStr);
                }
            }

            Decoder coder = decoderFactory.getDecoder(getAccessName());
            if (coder != null) {
                errorStr = coder.encoder(errorStr);
            }

            logger.error("由于CIP在" + accessControl.getCipReturnTimeOut() + "ms内未返回，则返回错误信息。" + System.getProperty("line.separator")
                    + "解密后的报文：" + messageObject.getDecryptMsg() + System.getProperty("line.separator")
                    + "返回报文：" + errorStr);

            ByteBuf encoded = Unpooled.copiedBuffer(errorStr.getBytes());
            this.ctx.writeAndFlush(encoded).addListener(CLOSE);
        }
    }
}
